#include "../src/dulinklist.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* 声明底层链表的函数库 */
extern func_DLinkList fun_DLinkList;

typedef struct __value
{
    DLinkListNode node;
    int data;
} value_t;

int main(int argc, const char *argv[])
{
    int i; 

    value_t* pv = NULL;
    value_t v1, v2, v3, v4, v5;

    v1.data = 1;
    v2.data = 2;
    v3.data = 3;
    v4.data = 4;
    v5.data = 5;

    DLinkList *dlist = fun_DLinkList.create();

    // 分别为头插入和尾插入，先简单的测试其中的一种，免得看数据乱
#if  0
    fun_DLinkList.insert(dlist, (DLinkListNode *)&v1, fun_DLinkList.length(dlist));
    fun_DLinkList.insert(dlist, (DLinkListNode *)&v2, fun_DLinkList.length(dlist));
    fun_DLinkList.insert(dlist, (DLinkListNode *)&v3, fun_DLinkList.length(dlist));
    fun_DLinkList.insert(dlist, (DLinkListNode *)&v4, fun_DLinkList.length(dlist));
    fun_DLinkList.insert(dlist, (DLinkListNode *)&v5, fun_DLinkList.length(dlist));
#else
    fun_DLinkList.insert(dlist, (DLinkListNode *)&v1, 0);
    fun_DLinkList.insert(dlist, (DLinkListNode *)&v2, 0);
    fun_DLinkList.insert(dlist, (DLinkListNode *)&v3, 0);
    fun_DLinkList.insert(dlist, (DLinkListNode *)&v4, 0);
    fun_DLinkList.insert(dlist, (DLinkListNode *)&v5, 0);
#endif

    // 复位游标开始后面的测试工作
    fun_DLinkList.reset(dlist);
    printf("\n链表中的数据 ：");
    for (i = 0; i < fun_DLinkList.length(dlist); i++)
    {
        pv = (value_t *)fun_DLinkList.get(dlist, i);
        printf("%d\t", pv->data);
    }
    printf("\n");

    printf("循环链表证明 ：");
    
    for (i = 0; i < 2 * fun_DLinkList.length(dlist); i++)
    {
        // 区别于上面的使用 get 的方法，此处测试使用 next + current 的方式遍历
        pv = ( value_t *)fun_DLinkList.current(dlist);
        fun_DLinkList.next(dlist);
        printf("%d\t", pv->data);
    }
    printf("\n");


    pv = ( value_t *)fun_DLinkList.delete(dlist, 1);
    printf("删除位置 1为 ： %d\n", pv->data);
    
    printf("删除后的数据 ：");
    for (i = 0; i < fun_DLinkList.length(dlist); i++)
    {
        // 区别于上面的使用 next + current 的方法，此处测试使用 next 的方式遍历
        pv = ( value_t *)fun_DLinkList.next(dlist);
        printf("%d\t", pv->data);
    }
    printf("\n");


    pv = ( value_t *)fun_DLinkList.delete(dlist, 0);
    printf("头删除的数据 ：%d\n", pv->data);
    fun_DLinkList.reset(dlist);
    printf("头删后的数据 : ");
    for (i = 0; i < 2 * fun_DLinkList.length(dlist); i++)
    {
        pv = ( value_t *)fun_DLinkList.next(dlist);
        printf("%d\t", pv->data);
    }
    printf("\n");

    // 复位游标指针，使用 prev 进行遍历
    fun_DLinkList.reset(dlist);
    fun_DLinkList.prev(dlist);
    printf("\n链表中的数据 ：");
    for (i = 0; i < fun_DLinkList.length(dlist); i++)
    {
        pv = (value_t *)fun_DLinkList.prev(dlist);
        printf("%d\t", pv->data);
    }
    printf("\n");

    // 复位游标指针，使用 prev 进行遍历
    fun_DLinkList.reset(dlist);
    fun_DLinkList.prev(dlist);
    printf("循环证明数据 ：");
    for (i = 0; i < 2 * fun_DLinkList.length(dlist); i++)
    {
        pv = (value_t *)fun_DLinkList.prev(dlist);
        printf("%d\t", pv->data);
    }
    printf("\n");
    
    // 清空 + 销毁链表
    fun_DLinkList.clear(dlist);
    fun_DLinkList.destroy(&dlist);

    if(dlist == NULL) 
    {
        printf("\nfree success\n\n");
    }    
    else
    {
        free(dlist);
        printf("\nfree failed!\n\n");
    }
    
    return 0;
}

